<!--  -->
<template>
    <div class="three3div" :style="{width:`${innerWidth}px`,height:`${innerHeight}px`}">
        <div id="threedPei" :style="{width:`${innerWidth}px`,height:`${innerHeight}px`}" class=" _3dpiebg"></div>
        <div class="labelPie">
            <div class="d-flex mt20" v-for="(item,index) in arry" :key="index" @mouseenter="getValue(item.name)" @mouseleave="noValue()">
                <div class="list" :style="{background:item.color}"></div>
                <div>{{item.name}}</div>
            </div>
        </div>
        <div class="showValue" v-show="isShow">
            <div style="font-size:40px;">{{column}}%</div>
            <div style="font-size:24px;padding-top:7px;">{{columnName}}</div>
        </div>
    </div>
</template>

<script>
var scene,camera,renderer,ambientLight,directionalLight;//分别对应场景，相机，渲染器，环境光，方向光
var arr = [];
let moveBlock = '';
// 创建场景
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
// var loader = new THREE.ObjectLoader();
export default {
    data () {
        return {
            isShow:false,
            column:"",
            columnName:'',
            ringGroup : []
        };
    },
    props:{
        arry:{
            type: Array,
            default:() => []
        },
        innerWidth:{
            type:Number,
            default:640
        },
        innerHeight:{
            type:Number,
            default:320
        },
    },
    watch: {
        arry:{
            handler(){
                //移出渲染模型,环境和照射光源，释放内存
                scene.remove(ambientLight);
                scene.remove(directionalLight);
                for(let item of this.ringGroup){
                    scene.remove(item);
                }
                let element,pElements = document.getElementById("threedPei").getElementsByTagName('canvas');
                // 删除所有cavans
                while (pElements.length>0) {
                    element = pElements[0];
                    element.parentElement.removeChild(element);
                }
                this.initPei();   
            }
        }
    },
    created(){},
    mounted(){
    },
    methods: {
        initPei (){
            var all = 0;
            arr = [];
            this.ringGroup = [];
            for(var i of this.arry){
                all += parseInt(i.value);
            }
            var len = this.arry.length;
            for(var k in this.arry){
                var startHorn = null,endHorn = null,val = null;
                val = (parseInt(this.arry[k].value)/all*2).toFixed(2);
                if(k == 0){
                    startHorn = 0;
                    endHorn = val;
                }else if(k > 0 && k < len-1){
                    startHorn = arr[k-1].endHorn + arr[k-1].startHorn;
                    endHorn = val;
                }else if(k == len-1){
                    startHorn = arr[k-1].endHorn + arr[k-1].startHorn;
                    // console.log(arr[k-1].endHorn,arr[k-1].startHorn)
                    endHorn = 2-startHorn;
                }
                arr.push({color:this.arry[k].color,startHorn:parseFloat(startHorn),endHorn:parseFloat(endHorn),name:this.arry[k].name})
            }
            // scene.background = new THREE.Color( 0xa0a0a0 );
            // 创建相机
            camera = new THREE.PerspectiveCamera(30, this.innerWidth/this.innerHeight, 0.1, 1000);
            // 渲染器
            renderer.setSize(this.innerWidth, this.innerHeight);
            renderer.setClearAlpha(0);
            // 创建环境光
            ambientLight = new THREE.AmbientLight( 0xf9f9f9 );
            scene.add( ambientLight );
            // 创建方向光
            directionalLight = new THREE.DirectionalLight( 0x444444 );
            directionalLight.position.set( .5, 0.75, 0.5 ).normalize();
            scene.add( directionalLight );
            this.makeRing();
            camera.position.x = -30;
            camera.position.y = 50;
            camera.position.z = 60;
            camera.lookAt(new THREE.Vector3(0, 0, 0));
            renderer.render(scene, camera);
            this.renderScene();
            document.getElementById("threedPei").addEventListener('mousemove', this.onDocumentMouseMove, false);
            document.getElementById("threedPei").appendChild(renderer.domElement);
        },
        renderScene() {
            renderer.clear();
            requestAnimationFrame(this.renderScene);
            renderer.render(scene, camera);
        },
        // 创建几何体
        createMesh(geom,color) {
            var cylinderMat = new THREE.MeshLambertMaterial({//创建材料
                color:color,
                wireframe:false
            });
            var mesh = new THREE.Mesh(geom, cylinderMat);
            return mesh;
        },
        // 创建单个圆环
        makeRing(){
            var geometry = new THREE.BoxGeometry(40, 4, 0);
            var material = new THREE.MeshBasicMaterial({
                color: 0xfff
            });
            let start = .5;
            for(let i of arr){
                var cube1;
                var cube2;
                cube1 = new THREE.Mesh(geometry, material);
                cube2 = new THREE.Mesh(geometry, material);
                cube1.rotateY(Math.PI * (start+i.startHorn))
                cube2.rotateY(Math.PI * (start+i.startHorn+i.endHorn))
                var geoBig = this.createMesh(new THREE.CylinderGeometry(20, 20, 4, 100, 4, false, Math.PI *i.startHorn, Math.PI *i.endHorn),i.color);
                var geoSm = this.createMesh(new THREE.CylinderGeometry(10, 10, 4, 100, 4, false, Math.PI *i.startHorn, Math.PI *i.endHorn),i.color);
                var bigBSP = new ThreeBSP(geoBig);
                var smBSP = new ThreeBSP(geoSm);
                var cubeBSP1 = new ThreeBSP(cube1);
                var cubeBSP2 = new ThreeBSP(cube2);
                var smBlocks
                //进行并集计算
                var resultBSP = bigBSP//.subtract(smBSP);
                if(i.endHorn > 1){
                    resultBSP = bigBSP.subtract(smBSP);
                    smBlocks = resultBSP.subtract(cubeBSP1.subtract(cubeBSP2))
                }else{
                    var smBlock1 = resultBSP.subtract(cubeBSP1)//.subtract(cubeBSP1.intersect(cubeBSP2))
                    var smBlock2 = resultBSP.intersect(cubeBSP2)//.subtract(cubeBSP1.intersect(cubeBSP2))
                    smBlocks = smBlock1.intersect(smBlock2).subtract(smBSP)
                }       
                //从BSP对象内获取到处理完后的mesh模型数据
                var smBlock = smBlocks.toMesh();
                //更新模型的面和顶点的数据
                smBlock.geometry.computeFaceNormals();
                smBlock.geometry.computeVertexNormals();       
                //重新赋值一个纹理
                material = new THREE.MeshLambertMaterial({//创建材料
                    color:i.color,
                    wireframe:false
                });
                smBlock.material = material;
                smBlock.name = i.name;
                this.ringGroup.push(smBlock);
                // 添加到场景中
                scene.add(smBlock);
            }
        },
// 鼠标点击事件
        onDocumentMouseMove(event) {
            var vector = new THREE.Vector3(( event.offsetX / this.innerWidth ) * 2 - 1, -( event.offsetY / this.innerHeight ) * 2 + 1, 0.5);
            vector = vector.unproject(camera);
            var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
            var intersects = raycaster.intersectObjects(this.ringGroup);
            if (intersects.length > 0) {
                if(moveBlock !== ''){
                    if(moveBlock.name !== intersects[0].object.name){
                        moveBlock.scale.y = 1;
                        moveBlock.position.y = 0;
                    }
                    this.hideValue();
                }
                moveBlock = intersects[0].object;
                intersects[0].object.scale.y = 2;
                intersects[0].object.position.y = 2;
                this.shopValue(moveBlock.name);
            }else{
                if(moveBlock !== ''){
                    moveBlock.scale.y = 1;
                    moveBlock.position.y = 0;
                }
                this.hideValue();
            }
        },
        //比例显示
        shopValue(name){
            this.isShow = true;
            let allCount = 0;
            let arrList = [];
            for(let item of this.arry){
                allCount+=Number(item.value);
            }
            for(let item of this.arry){
                let arr = {};
                arr.value = (item.value/allCount*100).toFixed(2);
                arr.name = item.name;
                arrList.push(arr);
            }
            for(let item of arrList){
                if(item.name == name){
                    this.column = item.value;
                    this.columnName = item.name;
                }
            }
        }, 
        hideValue(){
            this.isShow = false;
        },
        getValue(name){
            var nameNode = scene.getObjectByName ( name );
            scene.traverse(function(obj) {
                obj.scale.y = 1;
                obj.position.y = 0;
            })
            nameNode.scale.y = 2;
            nameNode.position.y = 2;
            this.shopValue(name);
        },
        noValue(){
            this.hideValue();
            scene.traverse(function(obj) {
                obj.scale.y = 1;
                obj.position.y = 0;
            })
        }
    }
}
</script>

<style  scoped>
    canvas {width:100%;height:100%;}
    .three3div{
        position:relative;z-index:10;
    }
    .labelPie{
        position:absolute;
        top:50%;
        right:30px;
        margin-top:-58px;
        color: #9da5b7;
    }
    .labelPie div{
        cursor: pointer;
    }
    .labelPie .list{
        width: 16px;
        height:16px;
        margin-right: 5px;
    }
    .showValue{
        position:absolute;
        top:50%;
        left:50%;
        z-index: 200;
        width: 160px;
        margin-left: -80px;
        margin-top:-40px;
        text-align: center;
    }
    .d-flex{
        display: flex;
    }
    .mt20{
        margin-top: 20px;
    }
</style>